package com.jeesite.modules.stock.service;

import com.jeesite.common.lang.StringUtils;
import com.jeesite.common.utils.ThreadUtils;
import com.jeesite.modules.dp.dao.column.DpColumnDao;
import com.jeesite.modules.dp.entity.column.DpColumn;
import com.jeesite.modules.stock.dao.StockDailyDao;
import com.jeesite.modules.stock.dao.StockLogoDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;

import javax.annotation.PostConstruct;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

public abstract class AbstractStockService {

    @Autowired
    private StockDailyDao stockDailyDao;

    @Autowired
    private StockLogoDao stockLogoDao;

    @Autowired
    private DpColumnDao dpColumnDao;

    private final long year20Mills = 630720000000L;

    public static final Set<String> allConfigedColumnKeys = new HashSet<>();

    @PostConstruct
    public void loadDpColumns() {
        Thread.ofVirtual().start(() -> {
            while (true) {
                List<DpColumn> columns = dpColumnDao.findList(new DpColumn());
                columns.removeIf(item -> StringUtils.isBlank(item.getColumnKey())
                        || StringUtils.isBlank(item.getColumnDataindex()));
                List<String> keys = columns.stream()
                        .map(DpColumn::getColumnDataindex)
                        .collect(Collectors.toList());
                allConfigedColumnKeys.addAll(keys);
                ThreadUtils.sleep(1000 * 30);
            }
        });
    }

    protected String dateFormat(String date) {
        try {
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.sss'Z'");
            df.setTimeZone(TimeZone.getTimeZone("UTC"));
            Date after = df.parse(date);
            after.setTime(after.getTime() + 24 * 3600 * 1000);
            df.applyPattern("yyyy-MM-dd");
            df.setTimeZone(TimeZone.getDefault());

            return df.format(after);
        } catch (ParseException e) {
            return "";
        }
    }

    /**
     * 时间排序
     *
     * @param dt1 时间1
     * @param dt2 时间2
     * @return [min, max]
     */
    protected String[] sortBeginAndEndTime(String dt1, String dt2, String format) {
        try {
            SimpleDateFormat fr = new SimpleDateFormat(format);
            Date date1 = fr.parse(dt1);
            Date date2 = fr.parse(dt2);
            if (date1.getTime() > date2.getTime()) {
                return new String[]{dt2, dt1};
            } else {
                return new String[]{dt1, dt2};
            }
        } catch (ParseException e) {
            e.printStackTrace();
            throw new RuntimeException("时间格式有误");
        }
    }

    protected void validateDate(String date) {
        try {
            SimpleDateFormat fr = new SimpleDateFormat("yyyy-MM-dd");
            Date d = fr.parse(date);
            Date now = new Date();
            if (d.getTime() >= (now.getTime() + 24 * 3600 * 1000)
                    || d.getTime() < now.getTime() - year20Mills) {
                throw new RuntimeException("时间超过范围");
            }
        } catch (ParseException e) {
            throw new RuntimeException("时间格式有误");
        }
    }

    /**
     * 从startDate开始，往上找最近一个开盘日
     *
     * @param startDate 开始时间
     * @return 最近开盘日
     */
    protected String getKaipanDateOfStart(String startDate, int step) {
        try {
            SimpleDateFormat fr = new SimpleDateFormat("yyyy-MM-dd");
            Date date = fr.parse(startDate);
            int count = stockDailyDao.findCountOfDate(startDate);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            int cr = 0;
            while (count < 100) {
                calendar.add(Calendar.DAY_OF_MONTH, step);
                count = stockDailyDao.findCountOfDate(fr.format(calendar.getTime()));
                cr++;
                if (cr > 15) {
                    break;
                }
            }
            if (count > 100) {
                return fr.format(calendar.getTime());
            } else {
                throw new RuntimeException("日期有误");
            }
        } catch (ParseException e) {
            throw new RuntimeException("日期格式有误");
        }
    }

    /**
     * 从endDate开始向下找最近一个开盘日
     *
     * @param endDate 截至日期
     * @return 最近开盘日
     */
    protected String getKaipanDateOfEndDate(String endDate) {
        try {
            SimpleDateFormat fr = new SimpleDateFormat("yyyy-MM-dd");
            Date date = fr.parse(endDate);
            int count = stockDailyDao.findCountOfDate(endDate);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            int cr = 0;
            while (count < 100) {
                calendar.add(Calendar.DAY_OF_MONTH, -1);
                count = stockDailyDao.findCountOfDate(fr.format(calendar.getTime()));
                cr++;
                if (cr > 15) {
                    break;
                }
            }
            if (count > 100) {
                return fr.format(calendar.getTime());
            } else {
                throw new RuntimeException("日期有误");
            }
        } catch (ParseException e) {
            throw new RuntimeException("日期格式有误");
        }
    }
}
